<?php
/**
 * 天马供应商SDK
 * @author 陈韵
 */
namespace App\Service\VendorClient\Shoplongtan;
use App\Service\Code\Normal;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;
use App\Model\PssModel\ServiceConfig;

class ShoplongtanApiClient
{
    private $account  = 'Shoplongtan';
    protected $config;
    protected $RouteMap = [
        'getAccessToken'        => '/api/getToken',
        'queryGoodsList'        => '/api/goods/get_list',
        'createOrder'           => '/api/orderService/pushOrder2',
        'cancelOrder'           => '/api/order/cancel',
    ];
    

    public function __construct($apiBody = []){
        $this->config = $apiBody;
    }

    /**
     * 创建订单
     * @param array $params
     * @return mixed
     */
/**
     * 创建订单
     */
    public function createOrder( $params = [] )
    {
        if( empty($params['supplierOrder']) || empty($params['orderGoods']) || empty($params['order']) || empty($params['binfo']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder or orderGoods or order or binfo");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        $order     = $params['order'];
        $binfo     = $params['binfo'];
        $deliver_money  = $orderInfo['deliver_money'];
        $order_goods= [];
        $productAmt = 0;
        $supplier_skuid_map = $params['supplier_skuid_map'];

        //获取下单商品信息
        foreach ($params['orderGoods'] as $key => $item )
        {
            if(empty($supplier_skuid_map[$item['supplier_skuid']])){

                return Normal::returnCode(Normal::FAIL,"供应商商品ID".$item['supplier_skuid']."数据不存在，请核实！");
            }
            //卖价
            $price              = $item['price'];
            //商品购买数量
            $quantity           = $item['quantity'];
            $totalGoods         = bcmul((string)$price,(string)$quantity);
            $order_goods[]= [
                'goods_spu'     => (string)$item['supplier_skucode'],
                'sku_id'        => (string)$supplier_skuid_map[$item['supplier_skuid']][$item['spec_num']],
                'goods_num'     => $quantity,
                'goods_price'   => $price,
            ];
            $productAmt = bcadd((string)$productAmt,(string)$totalGoods,2);
        }
        //实际下单金额
        $real_total_money   = $orderInfo['real_total_money'];
        
        //订单总金额 = 含税商品总金额 + 运费 - 优惠金额
        $ActualPaidAmt      = bcadd((string)$deliver_money,(string)$productAmt);
        //优惠金额
        $discount_money     = bcsub((string)$ActualPaidAmt,$real_total_money);

        //下单支付的时候支付信息
        $apply_extends  = @json_decode($orderInfo['apply_extends'],true);
        
        //支付时间
        $payTime        = empty($order['payTime']) ? $orderInfo['pay_time'] :$order['payTime'];
        //支付时间
        $pay_time       = $payTime ? $payTime : time();
        //$pay_time       = date('Y-m-d H:i:s',$pay_time);
        
        //支付流水号
        $pay_sn         = $order['paySerial']??$orderInfo['pay_sn'];

        //支付公司信息
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $payCommanyName = $apply_extends['payCommanyName'] ?? '';
        $PayCompanyCode = $order['payCommanyCode'] ? $order['payCommanyCode'] : $payCommanyCode;
        $payCommanyName = $order['payCommanyName'] ? $order['payCommanyName'] : $payCommanyName;
        //电商平台信息
        $enterpriseNum = $apply_extends['enterpriseNum'] ?? '';
        $enterpriseName = $apply_extends['enterpriseName'] ?? '';
        $enterpriseNum = $order['enterpriseNum'] ? $order['enterpriseNum'] : $enterpriseNum;
        $enterpriseName = $order['enterpriseName'] ? $order['enterpriseName'] : $enterpriseName;
        $pay_value      = ServiceConfig::instance()->getConfigByEventsValue($this->account, ServiceConfig::TYPE_PAY, $PayCompanyCode);
        if (empty($pay_value)) {
            return Normal::returnCode(Normal::FAIL, "支付公司编码：【{$PayCompanyCode}】未映射，请联系云仓管理员处理");
        }
        //获取区域id
        $area_id = '';
        $areaRequestParam = [
            'method'    => 'queryArea',
            'data'      => [
                'name' => $orderInfo["province"]." ".$orderInfo["city"]." ".$orderInfo["district"]
            ],
        ];
        $area = $this->areaExecute($areaRequestParam);
        if($area["code"]!= Normal::SUC or !isset($area["data"]["Message"]) or empty($area["data"]["Message"])){
            return Normal::returnCode(Normal::FAIL,"当前区域地址匹配获取错误，请联系上游服务商进行处理之后，再重新推送订单！【".json_encode($area,JSON_UNESCAPED_UNICODE).'】');
        }
        $area_id = $area["data"]["Message"];
        //创建订单数据
        $data = [[
            'ebpCode'               => $PayCompanyCode,
            'ebpName'               => $payCommanyName,
            'paycomCode'            => $enterpriseNum,
            'paycomName'            => $enterpriseName,
            'payOrderNo'            => $pay_sn,
            'contactName'           => $orderInfo["receive_name"],
            'contactCode'           => "",
            'buyerName'             => $orderInfo['buyer_realname'],
            'ConsigneeCode'         => $orderInfo['buyer_idcard'],
            'contactMobile'         => $orderInfo['buyer_phone'],
            'area_id'               => $area_id,
            'contactAddr'           => $orderInfo["province"].$orderInfo["city"].$orderInfo["district"],
            'detailAddr'            => $orderInfo["receive_address"],
            'orderId'               => $orderInfo['supplier_dsn'],
            'amount'                => $productAmt,
            'distributionfee'       => $deliver_money,
            'discount'              => $discount_money,
            'realPayment'           => $real_total_money,
            'source_platform_no'    => $orderInfo['supplier_dsn'],
            'pay_time'              => $pay_time,
            'tradeType'             => '002',
            'order_goods'           => $order_goods,
            'pay_type'              => $pay_value,
        ]];
        $requestParam = [
            'method'    => 'createOrder',
            'data'      => ['data' => json_encode($data,JSON_UNESCAPED_UNICODE)],
        ];
        $res  = $this->execute($requestParam);
        return $res;
    }
    /**
     * 取消订单
     */
    public function cancelOrder($params = []) {
        $thirdpart_order_sn = $params['supplierOrder']['thirdpart_order_sn'];
        $data =[
            'order_id' => $thirdpart_order_sn,
            'precheck' => 'false',//退款预检false:则直接申请
        ];
        $requestParam = [
            'method'    => 'cancelOrder',
            'data'      => $data
        ];
        return  $this->execute($requestParam);
    }
    /**
     * 查询商品信息
     */
    public function queryGoodsList($param)
    {
        //获取商品列表
        $goodsWhere = [
            'page'      => $param['page']  ?? 1,
            'limit'     => $param['limit']  ?? 20,
        ];
        $requestParam = [
            'method'    => 'queryGoodsList',
            'data'      => $goodsWhere,
        ];
        $res  = $this->execute($requestParam);
        if($res["code"] != Normal::SUC or !isset($res["data"]["data"]["data"]) or empty($res["data"]["data"]["data"])){
            return $res;
        }
        $result_query_goods = $res["data"]["data"]["data"];
        foreach ($result_query_goods as $goods => $goodsItem) 
        {
            $attrMap = array_column($goodsItem['attr'],null,'attribute_id');
            $rule = $goodsItem['rule'];
            $newSpecList = [];
            foreach ($rule as $spec) 
            {                
                $spec_sku = explode("_", $spec['spec_sku']);
                if( !empty($spec_sku[0]) && !empty($attrMap[$spec_sku[0]]) && !empty($attrMap[$spec_sku[0]]['name']) && $attrMap[$spec_sku[0]]['name'] == '保质期' ) 
                {
                    $batchNo = $attrMap[$spec_sku[0]]['attribute_name'];
                    $expire  = $attrMap[$spec_sku[0]]['attribute_name'] ? date("Y-m-d",strtotime($attrMap[$spec_sku[0]]['attribute_name'])) : '0000-00-00 00:00:00';
                } else {
                    $batchNo = '基准批次';
                    $expire  = '0000-00-00 00:00:00';
                }
                
                if( !empty($spec_sku[1]) && !empty($goodsItem['unit_name']) && !empty($attrMap[$spec_sku[1]]['attribute_name']) ) 
                {
                    $SpecNum = str_replace($goodsItem['unit_name'],"", $attrMap[$spec_sku[1]]['attribute_name']);
                } else {
                    $SpecNum = 1;
                }
                $newSpecList[$batchNo][] = [
                    'BatchNo'   => $batchNo,
                    'SpecID'    => $spec['goods_sku'],
                    'SpecNum'   => $SpecNum,
                    'SpecPrice' => $spec['sku_price'],
                    'SpecStock' => $spec['sku_stock'],
                    'Expire'    => $expire
                ];
            }
            unset($result_query_goods[$goods]["rule"]);
            unset($result_query_goods[$goods]["attr"]);
            $result_query_goods[$goods]['newSpecList']= $newSpecList;
        }
        if( empty($result_query_goods)) {
            return Normal::returnCode(Normal::SUC,"获取成功",[
                'data'      => [],
                'has_next'  => false
            ]);
        }
    
        return Normal::returnCode(Normal::SUC,"获取成功",[
            'data'      => $result_query_goods,
            'has_next'  => true
        ]);
    
    }
    
//     /**
//      * 查询商品信息
//      */
//     public function queryGoodsList($param)
//     {
//         //获取商品列表
//         $goodsWhere = [
//             'page'      => $param['page']  ?? 1,
//             'limit'     => $param['limit']  ?? 20,
//         ];
//         $requestParam = [
//             'method'    => 'queryGoodsList',
//             'data'      => $goodsWhere,
//         ];
//         $res  = $this->execute($requestParam);
//         if($res["code"] != Normal::SUC or !isset($res["data"]["data"]["data"]) or empty($res["data"]["data"]["data"])){
//             return $res;
//         }
//         $result_query_goods = $res["data"]["data"]["data"];
//         $details = [];
//         foreach ($result_query_goods as $sku)
//         {
//             //处理规格数据
//             $attr_list = [];
//             foreach ($sku['attr'] as $attr){
//                 $attr_list[$attr["attribute_id"]] = $attr;
//             }
    
//             $unit_name  = $sku["unit_name"];
//             $rule       = $sku['rule'];
    
//             foreach ($rule as $r){
    
//                 $spec_sku = $r["spec_sku"];
    
//                 if(!empty($spec_sku)){
//                     $spec_list  = explode("_",$spec_sku);
//                     $spec_key   = end($spec_list);
//                     $attr_info  = $attr_list[$spec_key];
//                     if(!empty($attr_info)){
//                         $sku_num    = (int)str_replace($unit_name,"",$attr_info["attribute_name"]);
//                         $sku_price  =  $r["sku_price"];
//                         $sku_stock  =  $r["sku_stock"];
//                         $sku_name   =  $r["sku_name"];
//                         $goods_sku  =  $r["goods_sku"];
    
//                         //组装数据
//                         $details[]= [
//                             'goods_spu'             => $sku["goods_spu"],//商品货号
//                             'goods_name'            => $sku["goods_name"],//商品名称
//                             'goods_slideshow_img'   => $sku["goods_slideshow_img"],//商品图
//                             'barcode'               => $sku["barcode"],//国际条形码
//                             'brand_name'            => $sku["brand_name"],//品牌名
//                             'origin_name'           => $sku["origin_name"],//原产地
//                             'trade_type_id'         => $sku["trade_type_id"],//商品类型
//                             'trade_type_name'       => $sku["trade_type_name"],//商品类型
//                             'unit_name'             => $sku["unit_name"],//单位
//                             'category_name'         => $sku["category_name"],//分类
//                             'description'           => $sku["description"],//商品描述
//                             'is_sale'               => $sku["is_sale"],//上下架
//                             'sku_num'               => $sku_num,//规格数量
//                             'sku_price'             => $sku_price,//规格价格
//                             'sku_stock'             => $sku_stock,//规格库存
//                             'sku_name'              => $sku_name,//规格名称
//                             'stock_id'              => $goods_sku,//规格货号
//                         ];
//                     }
//                 }
//             }
//         }
    
//         if( empty($details)) {
//             return Normal::returnCode(Normal::SUC,"获取成功",[
//                 'data'      => [],
//                 'has_next'  => false
//             ]);
//         }
    
//         return Normal::returnCode(Normal::SUC,"获取成功",[
//             'data'      => $details,
//             'has_next'  => true
//         ]);
    
//     }
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    private function getToken( $param = [])
    {
        $redis = redis();
        $cache_key = $this->account."_AccessToken";
        $token = $redis->get($cache_key);
        $time = time();
        //判断token是否存在
        if(empty($token)) {
            $parameter = [
                'method'    => 'getAccessToken',
                'data'      => [
                    'merchantId'    => $this->config["merchantId"],
                    'timeStamp'     => time(),
                ],
            ];
            $res =$this->tokenExecute($parameter);
            if( $res['code'] != Normal::SUC ) {
                return $res;
            }
            $token  = $res["data"]["token"];
            $exp    = 60*60*2;
            $redis->set($cache_key,$token,$exp);
        }
        return Normal::returnCode(Normal::SUC,"获取成功",$token);
    }

    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    private function getSign( $param = [])
    {
        $string = '';
        //第一步：排升序
        ksort($param);
        //第二步：键名，键值依次拼接，末尾拼接秘钥
        foreach ($param as $k => $v){
            $string.= $k.$v; 
        }
        $string = $string.$this->config["sercet"];
        //第三步：base64加密
        $string = base64_encode($string);
        //第四步：md5加密
        $string = md5($string);
        //第五步：加密字符串转大写
        return strtoupper($string);
    }
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function areaExecute( $param = [] ){
    
        $method = $param["method"];
        $url    = $this->config["areaurl"];
        $parameter = [
            [
                'tag'    => 'Shoplongtan_' . $method,
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $url,
                'data'   => $param["data"],
                'method' => "post",
                'format' => 'json',
                'header' => []
            ]
        ];
        $resTask = TaskWorker::instance()->addTask($parameter);
        $resTask   = current($resTask);
        $response  = $resTask['response']['result'];
        $result    = @json_decode($response, true);
        if (isset($result['Status']) && $result["Status"] == 1) {
            return Normal::returnCode(Normal::SUC, "OK",$result);
        }
        $message = $result['message'] ?? '操作失败';
        return Normal::returnCode(Normal::FAIL, $message);
    }
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function tokenExecute( $param = [] ){
    
        $method = $param["method"];
        $url    = $this->config["baseurl"].$this->RouteMap[$method];
        $param["data"]["sign"] = $this->getSign($param["data"]);
        $parameter = [
            [
                'tag'    => 'Shoplongtan_' . $method,
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $url,
                'data'   => $param['data'],
                'method' => "post",
                'format' => '',
                'header' => []
            ]
        ];
        $resTask = TaskWorker::instance()->addTask($parameter,'handleDiableTask');
        $resTask   = current($resTask);
        $response  = $resTask['response']['result'];
        $result    = @json_decode($response, true);
        if (isset($result['code']) && $result["code"] == 10000) {
            return Normal::returnCode(Normal::SUC, "OK",$result['data']);
        }
        $message = $result['message'] ?? '操作失败';
        return Normal::returnCode(Normal::FAIL, $message);
    }
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] ){
        //获取token
        $token  = $this->getToken();
        if($token["code"] != Normal::SUC){
            return Normal::returnCode(Normal::FAIL, "token获取失效");
        }
        $Authorization = $token["data"];
        
        $method = $param["method"];
        $url    = $this->config["baseurl"].$this->RouteMap[$method];
        $parameter = [
            [
                'tag'    => 'Shoplongtan_' . $method,
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $url,
                'data'   => $param['data'],
                'method' => "post",
                'format' => 'x-www-form-urlencoded',
                'header' => [
                    "Content-Type:application/x-www-form-urlencoded;charset=utf-8",
                    "Authorization:Bearer {$Authorization}"
                ]
            ]
        ];

        if( in_array($method,['queryGoodsList','queryGoodsDetail']) ) {
            $resTask = TaskWorker::instance()->addTask($parameter,'handleDiableTask');
        } else {
            $resTask = TaskWorker::instance()->addTask($parameter);
        }
        $resTask   = current($resTask);
        $response  = $resTask['response']['result'];
        $result    = @json_decode($response, true);
        if (isset($result['code']) && $result["code"] == 10000) {
            return Normal::returnCode(Normal::SUC, "OK",$result);
        }
        $message = $result['message'] ?? '操作失败';
        return Normal::returnCode(Normal::FAIL, $message);
    }
}
    